using SharpDX;
using System.IO;

namespace Engine.FileFormats3D.C11Undercover.QADFile
{
    internal struct Light
    {
        #region Private Fields

        private float blinkDuaration;
        private float blinkOffset;
        private float blinkSize;
        private int color;
        private float cosinus;
        private float cosinus2;
        private int keineAhnung;
        private int keineAhnung10;
        private int keineAhnung11;
        private short keineAhnung2;
        private short keineAhnung3;
        private int keineAhnung4;
        private int keineAhnung5;
        private float keineAhnung6;
        private float keineAhnung7;
        private int keineAhnung8;
        private int keineAhnung9;
        private float orientationY;
        private float positionX;
        private float positionY;
        private float positionZ;
        private float sinus;
        private float sinus2;

        #endregion Private Fields

        #region Public Constructors

        public Light(Vector3 position)
        {
            this.blinkDuaration = 0;
            this.blinkOffset = 0;
            this.blinkSize = 0;
            this.color = 0;
            this.cosinus = 0;
            this.cosinus2 = 0;
            this.keineAhnung = 0;
            this.keineAhnung10 = 0;
            this.keineAhnung11 = 0;
            this.keineAhnung2 = 0;
            this.keineAhnung3 = 0;
            this.keineAhnung4 = 0;
            this.keineAhnung5 = 0;
            this.keineAhnung6 = 0;
            this.keineAhnung7 = 0;
            this.keineAhnung8 = 0;
            this.keineAhnung9 = 0;
            this.orientationY = 0;
            this.positionX = position.X;
            this.positionY = position.Y;
            this.positionZ = position.Z;
            this.sinus = 0;
            this.sinus2 = 0;
        }

        public Light(Vector3 position, System.Drawing.Color color)
            : this(position)
        {
            this.color = color.ToArgb();
        }

        #endregion Public Constructors

        #region Public Properties

        public float BlinkDuaration
        {
            get { return blinkDuaration; }
            set { blinkDuaration = value; }
        }

        public float BlinkOffset
        {
            get { return blinkOffset; }
            set { blinkOffset = value; }
        }

        public float BlinkSize
        {
            get { return blinkSize; }
            set { blinkSize = value; }
        }

        public int Color
        {
            get { return color; }
            set { color = value; }
        }

        public float OrientationY
        {
            get { return orientationY; }
            set { orientationY = value; }
        }

        public float PositionX
        {
            get { return positionX; }
            set { positionX = value; }
        }

        public float PositionY
        {
            get { return positionY; }
            set { positionY = value; }
        }

        public float PositionZ
        {
            get { return positionZ; }
            set { positionZ = value; }
        }

        #endregion Public Properties

        #region Public Methods

        public override string ToString()
        {
            return string.Format("XYZ{0};{1};{2}; color: {3}", this.positionX, this.positionY, this.positionZ, this.color);
        }

        #endregion Public Methods

        #region Internal Methods

        internal static Light FromStream(BinaryReader br)
        {
            // 70 Bytes per Light??
            Light light = new Light();
            long positionInArray = br.BaseStream.Position;

            light.keineAhnung = br.ReadInt32();
            light.BlinkSize = br.ReadSingle();
            light.BlinkOffset = br.ReadSingle();
            light.BlinkDuaration = br.ReadSingle();
            light.Color = br.ReadInt32();  // RGBA
            light.keineAhnung2 = br.ReadInt16();
            light.keineAhnung3 = br.ReadInt16();
            light.cosinus = br.ReadSingle();
            light.OrientationY = br.ReadSingle();
            light.sinus = br.ReadSingle();
            light.keineAhnung4 = br.ReadInt32();
            light.keineAhnung5 = br.ReadInt32();
            light.keineAhnung6 = br.ReadSingle(); // float 1;
            light.keineAhnung7 = br.ReadSingle(); // float 0:
            light.keineAhnung8 = br.ReadInt32();
            light.sinus2 = br.ReadSingle();
            light.keineAhnung9 = br.ReadInt32();
            light.cosinus2 = br.ReadSingle();
            light.keineAhnung10 = br.ReadInt32();

            // Position
            br.BaseStream.Position = positionInArray + 48;
            light.PositionX = br.ReadSingle();
            light.PositionY = br.ReadSingle();
            light.PositionZ = br.ReadSingle();

            // No Idea
            //light.keineAhnung11 = br.ReadInt32();
            //br.BaseStream.Position += 6;
            return light;
        }

        internal void Save(BinaryWriter bw)
        {
            bw.Write(this.keineAhnung);
            bw.Write(this.BlinkSize);
            bw.Write(this.BlinkOffset);
            bw.Write(this.BlinkDuaration);
            bw.Write(this.Color);
            bw.Write(this.keineAhnung2);
            bw.Write(this.keineAhnung3);
            bw.Write(this.cosinus);
            bw.Write(this.OrientationY);
            bw.Write(this.sinus);
            bw.Write(this.keineAhnung4);
            bw.Write(this.keineAhnung5);
            bw.Write(this.keineAhnung6);
            bw.Write(this.keineAhnung7);
            bw.Write(this.keineAhnung8);
            bw.Write(this.sinus2);
            bw.Write(this.keineAhnung9);
            bw.Write(this.cosinus2);
            bw.Write(this.keineAhnung10);
            bw.Write(this.PositionX);
            bw.Write(this.PositionY);
            bw.Write(this.PositionZ);
            bw.Write(this.keineAhnung11);
        }

        #endregion Internal Methods
    }
}